#include "http_server.h"
#include "logger.h"
#include <stdlib.h>
#include <string.h>
#include <jansson.h>

// 全局路由表
static http_route_t *g_routes = NULL;

// 默认路由处理函数（返回404）
static http_response_t *default_route_handler(const char *method, const char *path, 
                                             json_t *query_params, json_t *body, 
                                             void *user_data) {
    return http_response_error(404, "Route not found");
}

// 查找匹配的路由
static http_route_t *find_matching_route(const char *method, const char *path) {
    http_route_t *route = g_routes;
    while (route) {
        if (strcasecmp(route->method, method) == 0) {
            // 简化路径匹配，实际应该支持参数解析
            if (strcmp(route->path_pattern, path) == 0) {
                return route;
            }
        }
        route = route->next;
    }
    return NULL;
}

// HTTP请求处理回调
static int http_request_handler(void *cls, struct MHD_Connection *connection,
                              const char *url, const char *method,
                              const char *version, const char *upload_data,
                              size_t *upload_data_size, void **con_cls) {
    http_server_t *server = (http_server_t *)cls;
    
    // 如果是新连接，初始化上下文
    if (*con_cls == NULL) {
        http_request_context_t *context = malloc(sizeof(http_request_context_t));
        if (!context) {
            return MHD_NO;
        }
        memset(context, 0, sizeof(http_request_context_t));
        
        // 如果是POST请求，初始化post processor
        if (strcasecmp(method, "POST") == 0 || strcasecmp(method, "PUT") == 0) {
            context->post_processor = MHD_create_post_processor(connection, 8192, 
                                                               iterate_post_data, context);
            if (!context->post_processor) {
                free(context);
                return MHD_NO;
            }
        }
        
        *con_cls = context;
        return MHD_YES;
    }
    
    http_request_context_t *context = (http_request_context_t *)*con_cls;
    
    // 处理POST数据
    if (strcasecmp(method, "POST") == 0 || strcasecmp(method, "PUT") == 0) {
        if (*upload_data_size > 0) {
            MHD_post_process(context->post_processor, upload_data, *upload_data_size);
            *upload_data_size = 0;
            return MHD_YES;
        }
    }
    
    // 解析查询参数
    json_t *query_params = json_object();
    struct MHD_GetConnectionValues(connection, MHD_GET_ARGUMENT_KIND, 
                                  iterate_get_values, query_params);
    
    // 解析请求体（如果是JSON）
    json_t *body = NULL;
    if (context->post_data && context->post_data_size > 0) {
        json_error_t error;
        body = json_loads(context->post_data, 0, &error);
        if (!body) {
            LOG_WARN("Failed to parse JSON body: %s", error.text);
        }
    }
    
    // 查找匹配的路由
    http_route_t *route = find_matching_route(method, url);
    http_route_handler_t handler = route ? route->handler : default_route_handler;
    
    // 调用路由处理函数
    http_response_t *response = handler(method, url, query_params, body, server->user_data);
    
    // 清理
    if (body) json_decref(body);
    json_decref(query_params);
    
    if (!response) {
        response = http_response_error(500, "Internal server error");
    }
    
    // 发送响应
    struct MHD_Response *mhd_response = MHD_create_response_from_buffer(
        response->body_size, response->body, MHD_RESPMEM_MUST_COPY);
    
    if (!mhd_response) {
        http_response_free(response);
        return MHD_NO;
    }
    
    MHD_add_response_header(mhd_response, "Content-Type", response->content_type);
    MHD_add_response_header(mhd_response, "Access-Control-Allow-Origin", "*");
    MHD_add_response_header(mhd_response, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    MHD_add_response_header(mhd_response, "Access-Control-Allow-Headers", "Content-Type");
    
    int ret = MHD_queue_response(connection, response->status_code, mhd_response);
    MHD_destroy_response(mhd_response);
    http_response_free(response);
    
    // 清理请求上下文
    if (context->post_processor) {
        MHD_destroy_post_processor(context->post_processor);
    }
    if (context->post_data) {
        free(context->post_data);
    }
    free(context);
    *con_cls = NULL;
    
    return ret;
}

// POST数据迭代回调
static int iterate_post_data(void *cls, enum MHD_ValueKind kind, const char *key,
                           const char *filename, const char *content_type,
                           const char *transfer_encoding, const char *data,
                           uint64_t off, size_t size) {
    http_request_context_t *context = (http_request_context_t *)cls;
    
    // 忽略其他字段，只处理数据
    if (data && size > 0) {
        context->post_data = realloc(context->post_data, context->post_data_size + size + 1);
        if (!context->post_data) {
            return MHD_NO;
        }
        memcpy(context->post_data + context->post_data_size, data, size);
        context->post_data_size += size;
        context->post_data[context->post_data_size] = '\0';
    }
    
    return MHD_YES;
}

// GET参数迭代回调
static int iterate_get_values(void *cls, enum MHD_ValueKind kind, const char *key, const char *value) {
    json_t *query_params = (json_t *)cls;
    if (key && value) {
        json_object_set_new(query_params, key, json_string(value));
    }
    return MHD_YES;
}

int http_server_init(http_server_t *server, const char *host, int port, void *user_data) {
    if (!server || !host || port <= 0) {
        return ERROR_INVALID_PARAM;
    }

    memset(server, 0, sizeof(http_server_t));
    server->host = strdup(host);
    server->port = port;
    server->user_data = user_data;
    
    return SUCCESS;
}

int http_server_start(http_server_t *server) {
    if (!server || server->running) {
        return ERROR_INVALID_PARAM;
    }

    server->daemon = MHD_start_daemon(
        MHD_USE_SELECT_INTERNALLY, server->port, NULL, NULL,
        http_request_handler, server,
        MHD_OPTION_END);
    
    if (!server->daemon) {
        LOG_ERROR("Failed to start HTTP server on %s:%d", server->host, server->port);
        return ERROR_THREAD_CREATE;
    }
    
    server->running = true;
    LOG_INFO("HTTP server started on http://%s:%d", server->host, server->port);
    
    return SUCCESS;
}

int http_server_stop(http_server_t *server) {
    if (!server || !server->running) {
        return ERROR_INVALID_PARAM;
    }

    MHD_stop_daemon(server->daemon);
    server->daemon = NULL;
    server->running = false;
    
    LOG_INFO("HTTP server stopped");
    return SUCCESS;
}

void http_server_cleanup(http_server_t *server) {
    if (!server) {
        return;
    }

    http_server_stop(server);
    
    if (server->host) {
        free(server->host);
    }
    
    // 清理路由表
    http_route_t *route = g_routes;
    while (route) {
        http_route_t *next = route->next;
        free(route);
        route = next;
    }
    g_routes = NULL;
}

int http_server_add_route(http_server_t *server, const char *method, 
                         const char *path_pattern, http_route_handler_t handler) {
    if (!method || !path_pattern || !handler) {
        return ERROR_INVALID_PARAM;
    }

    http_route_t *new_route = malloc(sizeof(http_route_t));
    if (!new_route) {
        return ERROR_MEMORY_ALLOC;
    }

    new_route->method = method;
    new_route->path_pattern = path_pattern;
    new_route->handler = handler;
    new_route->next = g_routes;
    g_routes = new_route;
    
    return SUCCESS;
}

http_response_t *http_response_create(int status_code, const char *content_type, const char *body) {
    http_response_t *response = malloc(sizeof(http_response_t));
    if (!response) {
        return NULL;
    }

    response->status_code = status_code;
    response->content_type = content_type ? strdup(content_type) : strdup("text/plain");
    response->body = body ? strdup(body) : strdup("");
    response->body_size = response->body ? strlen(response->body) : 0;
    
    return response;
}

http_response_t *http_response_json(int status_code, json_t *json_body) {
    if (!json_body) {
        return http_response_error(500, "Invalid JSON body");
    }

    char *json_str = json_dumps(json_body, JSON_COMPACT);
    if (!json_str) {
        return http_response_error(500, "Failed to serialize JSON");
    }

    http_response_t *response = http_response_create(status_code, "application/json", json_str);
    free(json_str);
    
    return response;
}

http_response_t *http_response_error(int status_code, const char *error_message) {
    json_t *error_json = json_object();
    json_object_set_new(error_json, "error", json_boolean(true));
    json_object_set_new(error_json, "message", json_string(error_message));
    json_object_set_new(error_json, "status", json_integer(status_code));
    
    http_response_t *response = http_response_json(status_code, error_json);
    json_decref(error_json);
    
    return response;
}

void http_response_free(http_response_t *response) {
    if (!response) {
        return;
    }

    if (response->content_type) free(response->content_type);
    if (response->body) free(response->body);
    free(response);
}
